import { _decorator, Component, EventTouch, Input, input, instantiate, Node, ProgressBar, tween, Tween, UITransform, Vec2, Vec3 } from 'cc'
import DataManager from '../../Global/DataManager'
import { EntityTypeEnum, IActor, InputTypeEnum, toFixed } from '../../Common'
import { EntityManager } from '../../Base/EntityManager'
import { ActorStateMachine } from './ActorStateMachine'
import { EntityStateEnum, EventEnum } from '../../Enum'
import { WeaponManager } from '../Weapon/WeaponManager'
import { rad2Angle } from '../../Utils'
import EventManager from '../../Global/EventManager'
const { ccclass, property } = _decorator

@ccclass('ActorManager')
export class ActorManager extends EntityManager {

    id: number
    bulletType: EntityTypeEnum
    private hp: ProgressBar
    private targetPos: Vec3
    private tw: Tween<any>

    private wm: WeaponManager

    tick(dt) {
        if (this.id !== DataManager.Instance.myPlayerId) {
            return
        }

        if (DataManager.Instance.jm.input.length()) {
            const { x, y } = DataManager.Instance.jm.input
            EventManager.Instance.emit(EventEnum.ClientSync, {
                id: DataManager.Instance.myPlayerId,
                type: InputTypeEnum.ActorMove,
                direction: {
                    x: toFixed(x),
                    y: toFixed(y),
                },
                dt: toFixed(dt),
            })
            // 操作移交给发送网络数据了
            // DataManager.Instance.applyInput({
            //     id: 1,
            //     type: InputTypeEnum.ActorMove,
            //     direction: { x, y },
            //     dt,
            // })
            // this.state = EntityStateEnum.Run // 交给下面的动画 Tween 了
        } else {
            // this.state = EntityStateEnum.Idle // 交给下面的动画 Tween 了
        }
    }

    init(data: IActor) {
        this.id = data.id
        this.bulletType = data.bulletType
        this.hp = this.node.getComponentInChildren(ProgressBar)
        this.fsm = this.addComponent(ActorStateMachine)
        this.fsm.init(data.type)

        this.state = EntityStateEnum.Idle
        this.node.active = false

        // 初始化武器
        const prefab = DataManager.Instance.prefabMap.get(EntityTypeEnum.Weapon1)
        const weapon = instantiate(prefab)
        weapon.setParent(this.node)
        this.wm = weapon.addComponent(WeaponManager)
        this.wm.init(data)
    }

    render(data: IActor) {
        this.renderPos(data)
        this.renderDire(data)
        this.renderHP(data)
    }

    renderPos(data: IActor) {
        const { direction, position } = data
        const newPos = new Vec3(position.x, position.y)
        if (!this.targetPos) { // 第一次渲染位置
            this.node.active = true
            this.node.setPosition(newPos)
            this.targetPos = new Vec3(newPos)
        } else if (!this.targetPos.equals(newPos)) { // 位置发生变化才真正执行，因为数据每100毫秒才发一次，但是render是每帧
            this.tw?.stop() // 停止之前的动画
            this.node.setPosition(this.targetPos)
            this.targetPos.set(newPos)
            this.state = EntityStateEnum.Run
            this.tw = tween(this.node).to(0.1, {
                position: this.targetPos,
            }).call(() => {
                this.state = EntityStateEnum.Idle
            }).start()
        }
    }

    renderDire(data: IActor) {
        const { direction, position } = data

        if (direction.x !== 0) { // 角色根据左右移动方向进行翻转
            this.node.setScale(direction.x > 0 ? 1 : -1, 1)

            // 角色翻转之后，血条也要跟着翻转以保持不变
            this.hp.node.setScale(direction.x > 0 ? 1 : -1, 1)
        }

        // 根据移动角度设置武器的朝向
        const side = Math.sqrt(direction.x ** 2 + direction.y ** 2)
        const rad = Math.asin(direction.y / side)
        const angle = rad2Angle(rad)
        this.wm.node.setRotationFromEuler(0, 0, angle)
    }

    renderHP(data: IActor) {
        this.hp.progress = data.hp / this.hp.totalLength
    }
}